<template>
	<view class="content">
		<view class="container">
			<view @touchmove="move" ref="itemsContent" class="items-content">
				<view class="item" v-for="i in list"></view>
			</view>
			<view v-if="sliderWidth" class="slider">
				<view 
					@touchstart.stop="sliderButtonMoveStart" 
					@touchmove.stop="sliderButtonMove" 
					:style="{ 
						width: sliderWidth + 'px', 
						left: sliderLeft + 'px' 
					}" 
					class="slider-button"></view>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue';
	const ITEM_W = 40 + 20
	const CONTAINER_OFFSET = 15 * 2 + 2
	
	const itemsContent = ref()
	const list = ref(10)
	const sliderWidth = ref(0)
	const sliderLeft = ref(0)
	const moveData = ref({
		x: 0,
		left: 0
	})
	
	const contentViewWidth = ref(document.body.clientWidth - CONTAINER_OFFSET)
	const contentWidth = computed(() => ITEM_W * list.value)
	const silderContainerWidth = ref(document.body.clientWidth * 0.8)
	
	onMounted(() => {
		window.addEventListener('resize', resizeHandler)
		watchEffect(() => {
			if(!list.value) {
				sliderWidth.value = 0
			}
			sliderWidth.value = contentViewWidth.value / contentWidth.value * silderContainerWidth.value
		})
	})
	
	onUnmounted(() => {
		window.removeEventListener('resize', resizeHandler)
	})
	
	// 滚动条移动
	function move() {
		const left = itemsContent.value.$el.scrollLeft
		sliderLeft.value = getSliderScrollLeft(left)
	}
	
	// 滑动条拖动-开始
	function sliderButtonMoveStart(e: TouchEvent) {
		if(!e.touches[0]) {
			return
		}
		const { clientX } = e.touches[0]
		
		moveData.value.x = clientX
		moveData.value.left = 0
	}
	
	// 滑动条拖动-拖到中
	function sliderButtonMove(e: TouchEvent) {
		if(!e.touches[0]) {
			return
		}
		
		const { clientX } = e.touches[0]
		moveData.value.left = clientX - moveData.value.x
		
		sliderLeft.value = Math.max(
			0, 
			Math.min(
				sliderLeft.value + moveData.value.left, 
				silderContainerWidth.value - sliderWidth.value
			)
		)
		
		moveItems(sliderLeft.value)
		moveData.value.x = clientX
	}
	
	// 计算滑动条左侧偏移
	function getSliderScrollLeft(scrollLeft: number) {
		const leftRang = Math.min(scrollLeft / (contentWidth.value - contentViewWidth.value), 1)
		return Math.max(0, leftRang * (silderContainerWidth.value - sliderWidth.value))
	}
	
	// 移动滚动条
	function moveItems(scrollLeft: number) {
		if(!itemsContent.value.$el) {
			return
		}
		
		const scrollSliderWidth = contentViewWidth.value / contentWidth.value * contentViewWidth.value
		const leftRang = Math.min(scrollLeft / (silderContainerWidth.value - sliderWidth.value), 1)
		const left = leftRang * (itemsContent.value.$el.scrollWidth - scrollSliderWidth)
		itemsContent.value.$el.scrollTo({
			left
		})
	}
	
	function resizeHandler() {
		contentViewWidth.value = document.body.clientWidth - CONTAINER_OFFSET
	}
</script>

<style lang="scss" scoped>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}
	
	.container {
		height: 100px;
		width: 100%;
	}
	
	.items-content::-webkit-scrollbar {
	  display: none;
	}
	
	.items-content {
		border: 1px solid rgba(0,0,0,0.1);
		margin: 0 15px;
		display: flex;
		overflow: auto;
		scrollbar-width: none;
		-ms-overflow-style: none;
		.item {
			width: 40px;
			height: 40px;
			border-radius: 50%;
			background-color: indianred;
			flex-shrink: 0;
			margin: 10px;
		}
	}
	
	.slider {
		margin: 20px auto;
		border-radius: 10px;
		height: 10px;
		width: 80%;
		background-color: rgba(0,0,0,0.1);
		position: relative;
	}
	
	.slider-button {
		position: absolute;
		height: 10px;
		background-color: rgba(0,0,0,0.3);
		border-radius: 10px;
	}
</style>
